import { takeEvery, put, call, select, takeLatest } from 'redux-saga/effects'
// import { delay } from 'redux-saga'
import axios from 'axios'
import qs from 'querystringify'

import * as API from '../API/index.js'
import * as actions from '../actionTypes'
import { defaultValue } from '../reducers/editor'


let delay =  (ms, result = ms)=> {
	return new Promise(resolve => {
	  setTimeout(() => resolve(result), ms)
	})
  }

const Sk = window.Sk

function* checkUser() {
    const { userId } = yield select(state => state.user.userInfo)
    if (!userId) {
        yield put({
            type: actions.TOGGLE_LOGIN_MODAL,
            payload: {
                isOpen: true,
                isLogin: true,
            },
        })
        return false
    }
    return userId
}

export function* loadProject(action) {
    try {
        const userId = yield call(checkUser)
        if (!userId) {
            return
        }
        yield put({
            type: actions.TOGGLE_LOADING_PROJECT,
            payload: true,
        })
        const data = yield call(API.loadProject, {
            ...action.payload,
            userId,
            type: 1,
        })

        yield put({
            type: actions.LOAD_PROJECT_SUCCESS,
            payload: {
                data,
                listType: action.listType,
                isSearch: action.isSearch,
            },
        })
        yield delay(1000)
        yield put({
            type: actions.TOGGLE_LOADING_PROJECT,
            payload: false,
        })
    } catch (err) {
        console.log('err', err)
    }
}

export function* saveProject(action) {
    const { saveAs, saveAsName, publish } = action //另存为时
    const { value } = yield select(state => state.editor)
    const { projectName, projectDesc, projectId, lessonId } = yield select(
        state => state.project
    )
    console.log(projectDesc)
    const userId = yield call(checkUser)

    if (!userId) {
        return
    }

    if (!value) {
        yield put({
            type: actions.SHOW_TOAST,
            payload: '代码区内容为空哦，快去写点东西吧',
        })
        return
    }

    if (!projectName && !saveAs) {
        yield put({
            type: actions.TOGGLE_PROJECT_NAEM_MODAL,
            payload: {
                show: true,
                type: 'save',
            },
        })
        return
    }
    yield put({
        type: actions.SET_PROJECT_SAVE_STATUS,
        payload: 'saving',
    })

    let curProjectName = saveAs ? saveAsName : projectName
    const condition = {
        operation: 'S',
        userId,
        projectName: curProjectName,
        comment: projectDesc,
        projectId,
        pData: escape(encodeURIComponent(JSON.stringify(value))),
        type: 1,
        lessonId,
        thumbImg: 'https://res.miaocode.com/simile.png',
        // thumbImg: '', //假的缩略图，python项目不用
    }
    if (!projectId || saveAs) {
        delete condition.projectId
    }
    if (!lessonId) {
        delete condition.lessonId
    }
    if (publish) {
        yield put({ type: actions.TOGGLE_PUBLISH_MODAL, payload: true })
        yield put({ type: actions.TOGGLE_PLAYING_TRURLE, payload: false })
        // yield put({ type: actions.HANDLE_CLEAR_CONSOLE, payload: '' })
        yield delay(300)
        runCode(value)
    }
    const data = yield call(API.saveProject, condition)
    if (data.code === '000001' && data.data) {
        yield put({
            type: actions.SET_PROJECT_SAVE_STATUS,
            payload: 'success',
        })
        yield put({
            type: actions.SET_PROJECT_ID,
            payload: data.data.id,
        })
        yield put({
            type: actions.CHANGE_PROJECT_NAME,
            payload: curProjectName,
        })
        yield put({
            type: actions.TOGGLE_PROJECT_NAEM_MODAL,
            payload: {
                show: false,
                type: 'save',
            },
        })
    } else {
        yield put({
            type: actions.SET_PROJECT_SAVE_STATUS,
            payload: 'error',
        })
    }
    yield delay(1000)
    yield put({
        type: actions.SET_PROJECT_SAVE_STATUS,
        payload: 'save',
    })
}

export function* publishProject(action) {
    const userId = yield call(checkUser)
    const { value } = yield select(state => state.editor)
    const { projectName, projectDesc, projectId } = yield select(
        state => state.project
    )
    if (!userId) {
        return
    }
    try {
        if (!value) {
            yield put({
                type: actions.SHOW_TOAST,
                payload: '代码区内容为空哦，快去写点东西吧',
            })
            return
        }
        if (!projectName) {
            yield put({
                type: actions.SHOW_TOAST,
                payload: '还没有输入作品名称呦',
            })
            return
        }
        if (!projectId) {
            yield put({
                type: actions.SHOW_TOAST,
                payload: '发布出错啦，稍后再试吧',
            })
            return
        }

        yield put({ type: actions.TOGGLE_PUBLISH_LOADING, payload: true })

        const data = yield call(API.publishProject, {
            projectId,
            type: 1,
            comment: projectDesc,
            projectName,
        })
        if (data.code === '000001') {
            yield put({
                type: actions.SHOW_TOAST,
                payload: '发布成功啦',
            })
        }
        yield put({ type: actions.TOGGLE_PUBLISH_LOADING, payload: false })
        yield put({ type: actions.TOGGLE_PUBLISH_MODAL, payload: false })
    } catch (err) {
        console.log('err', err)
    }
}

export function* createNew(action) {
    if (Sk.TurtleGraphics && Sk.TurtleGraphics.reset) {
        Sk.TurtleGraphics.reset()
    }
    yield put({
        type: actions.TOGGLE_PLAYING_TRURLE,
        payload: false,
    })
}

function setLocation(action) {
    const _search = qs.parse(window.location.search)
    const newSearch = {
        ..._search,
        id: action.payload.id,
    }
    newSearch.lessonId && delete newSearch.lessonId
    window.location.search = qs.stringify(newSearch)
}

export function* getDataUrl(action) {
    yield put({
        type: actions.SET_PROJECT_ITEM,
        payload: action.payload,
    })

    const d = yield axios.get(action.payload.dataURL)
    if (d.data) {
        const codeValue = JSON.parse(decodeURIComponent(d.data))
        yield put({
            type: actions.PUT_EDITOR_VALUE,
            payload: codeValue,
        })
        yield put({
            type: actions.TOGGLE_PROJECT_MODAL,
            payload: false,
        })
        if (action.isMobile) {
            yield put({
                type: actions.SET_PLAYER_ITEM,
                payload: action.payload,
                code: codeValue,
            })
        }
    } else {
        yield put({
            type: actions.SHOW_TOAST,
            payload: '获取数据失败了，刷新试试吧',
        })
    }
}

function* openProjectModal(action) {
    const userId = yield call(checkUser)
    if (!userId) {
        return
    }
    yield put({
        type: actions.TOGGLE_PROJECT_MODAL,
        payload: true,
    })
}

function* saveAs(action) {
    const userId = yield call(checkUser)
    if (!userId) {
        return
    }
    yield put({
        type: actions.TOGGLE_PROJECT_NAEM_MODAL,
        payload: {
            show: true,
            type: 'save-as',
        },
    })
}

function* fetchDetail(action) {
    const data = yield call(API.getProjectById, {
        projectId: action.payload,
        type: 1,
    })
    if (data && data.dataURL) {
        yield call(getDataUrl, {
            payload: data,
            isMobile: action.isMobile,
        })
    } else {
        yield put({
            type: actions.SHOW_TOAST,
            payload: '打开作品出错',
        })
    }
}

export function* getLastModifyProject(action) {
    const _search = qs.parse(window.location.search)
    const { userId } = yield select(state => state.user.userInfo)
    if (!userId) {
        yield put({
            type: actions.PUT_EDITOR_VALUE,
            payload: defaultValue,
        })
        return
    }
    if (_search.id) {
        return
    }
    const data = yield call(API.getLastModifyProject, {
        userId,
        type: 1,
    })
    if (data && data.dataURL) {
        yield call(getDataUrl, {
            payload: data,
        })
    } else {
        yield put({
            type: actions.PUT_EDITOR_VALUE,
            payload: defaultValue,
        })
    }
}

export default function* watchProjects() {
    yield takeEvery(actions.CONFIRM_PUBLISH_PROJECT, publishProject)
    yield takeEvery(actions.LOAD_PROJECT_LIST, loadProject)
    yield takeLatest(actions.SAVE_PROJECT, saveProject) //防止重复
    yield takeEvery(actions.CREATE_NEW_PROJECT, createNew)
    yield takeEvery(actions.GET_PROJECT_DATAURL, setLocation)
    yield takeEvery(actions.OPEN_PROJECT_MODAL, openProjectModal)
    yield takeEvery(actions.GET_LAST_MODIFY_PROJECT, getLastModifyProject)
    yield takeEvery(actions.SAVE_PROJECT_AS, saveAs)
    yield takeEvery(actions.FETCH_PROJECT_DETAIL, fetchDetail)
}

const runCode = value => {
    if (Sk.TurtleGraphics.stop) {
        Sk.TurtleGraphics.stop()
    }
    Sk.TurtleGraphics.width = 344
    Sk.TurtleGraphics.height = 235
    Sk.TurtleGraphics.target = 'turtle-area-publish'
    Sk.inputfun = v => {
        return new Promise((resolve, reject) => {
            resolve('')
        })
    }
    Sk.misceval
        .asyncToPromise(function() {
            return Sk.importMainWithBody('<stdin>', false, value, true)
        })
        .then(res => {})
        .catch(err => {
            console.log('err')
        })
}



// WEBPACK FOOTER //
// ./src/sagas/project.js